package org.jeecg.demo.wx.controller;

import org.jeecg.common.api.vo.Result;
import org.jeecg.demo.wx.common.WXUserContext;
import org.jeecg.demo.wx.constant.CacheConstant;
import org.jeecg.demo.wx.convert.EScheduleUserCount2MapConvert;
import org.jeecg.demo.wx.entity.EScheduleUserCount;
import org.jeecg.demo.wx.enumeration.ScheduleStatusEnum;
import org.jeecg.demo.wx.service.IEScheduleUserCountService;
import org.jeecg.demo.wx.util.UpdateCountUtil;
import org.jeecg.demo.wx.vo.WXUserInfoVo;
import org.jeecg.modules.system.entity.SysDepart;
import org.jeecg.modules.system.entity.SysUser;
import org.jeecg.modules.system.entity.SysUserDepart;
import org.jeecg.modules.system.service.ISysDepartService;
import org.jeecg.modules.system.service.ISysUserDepartService;
import org.jeecg.modules.system.service.ISysUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;
import java.util.Map;
import java.util.Objects;

import static org.jeecg.demo.wx.constant.CacheConstant.WX_USER_INFO_KEY;

/**
 * 功能描述
 *
 * @author: zgq
 * @date: 2024年02月18日 19:39
 */
@RequestMapping("/wx/user")
@RestController
public class WXUserController {

    @Autowired
    private ISysUserService userService;

    @Autowired
    private ISysUserDepartService iSysUserDepartService;

    @Autowired
    private ISysDepartService departService;

    @Autowired
    private IEScheduleUserCountService iEScheduleUserCountService;

    @Autowired
    private UpdateCountUtil updateCountUtil;

    @GetMapping("/info")
    public Result<WXUserInfoVo> info() {
        String openId = WXUserContext.getOpenId();
        WXUserInfoVo wxUserInfoVo = new WXUserInfoVo();
        fillUserInfo(wxUserInfoVo, openId);
        return Result.ok(wxUserInfoVo);
    }

    @GetMapping("/userList")
    public Result<List<SysUser>> userList() {
        return Result.ok(userService.lambdaQuery().select(SysUser::getUsername, SysUser::getRealname).list());
    }

    private void fillUserInfo(WXUserInfoVo wxUserInfoVo, String openId) {
        // 填充用户信息
        SysUser sysUser = getUserInfoByOpenId(openId);
        if (sysUser != null) {
            wxUserInfoVo.setAvatar(sysUser.getAvatar());
            wxUserInfoVo.setName(sysUser.getRealname());
        }

        // 填充计数信息
        Map<Object, Object> objectMap = updateCountUtil.getCountMap(CacheConstant.WX_USER_INFO_KEY + openId);
        fillCount(wxUserInfoVo, openId, objectMap);

        // 填充部门信息
        String departName = getDepartNameByOpenId(openId);
        wxUserInfoVo.setDepart(departName);
    }

    private void fillCount(WXUserInfoVo wxUserInfoVo, String openId, Map<Object, Object> objectMap) {
        // 从 Redis 获取用户计数信息
        if (objectMap == null || objectMap.isEmpty()) {
            // 如果 Redis 中不存在用户计数信息，则从数据库中获取
            EScheduleUserCount eScheduleUserCount = getUserCountByOpenId(openId);
            if (eScheduleUserCount == null) {
                // 如果数据库中也不存在用户计数信息，则设置默认值
                setDefaultCount(wxUserInfoVo);
            } else {
                // 如果数据库中存在用户计数信息，则将其填充到 wxUserInfoVo 中，并更新 Redis
                fillCountFromDb(wxUserInfoVo, openId, eScheduleUserCount);
            }
        } else {
            // 如果 Redis 中存在用户计数信息，则直接从中获取
            fillCountFromRedis(wxUserInfoVo, objectMap);
        }
    }

    private void setDefaultCount(WXUserInfoVo wxUserInfoVo) {
        wxUserInfoVo.setReadCount(0);
        wxUserInfoVo.setUnreadCount(0);
        wxUserInfoVo.setCompletedCount(0);
        wxUserInfoVo.setUncompletedCount(0);
    }

    private void fillCountFromDb(WXUserInfoVo wxUserInfoVo, String openId, EScheduleUserCount eScheduleUserCount) {
        wxUserInfoVo.setReadCount(eScheduleUserCount.getReadCount());
        wxUserInfoVo.setUnreadCount(eScheduleUserCount.getUnreadCount());
        wxUserInfoVo.setCompletedCount(eScheduleUserCount.getCompletedCount());
        wxUserInfoVo.setUncompletedCount(eScheduleUserCount.getUncompletedCount());
        Map<String, Object> map = EScheduleUserCount2MapConvert.convert(eScheduleUserCount);
        updateCountUtil.putCountMap(openId, map);
    }

    private void fillCountFromRedis(WXUserInfoVo wxUserInfoVo, Map<Object, Object> objectMap) {
        wxUserInfoVo.setReadCount((Integer) objectMap.get(ScheduleStatusEnum.READ.getDesc()));
        wxUserInfoVo.setUnreadCount((Integer) objectMap.get(ScheduleStatusEnum.UNREAD.getDesc()));
        wxUserInfoVo.setCompletedCount((Integer) objectMap.get(ScheduleStatusEnum.FINISHED.getDesc()));
        wxUserInfoVo.setUncompletedCount((Integer) objectMap.get(ScheduleStatusEnum.UNDO.getDesc()));
    }

    private SysUser getUserInfoByOpenId(String openId) {
        return userService.lambdaQuery()
                .select(SysUser::getAvatar, SysUser::getRealname)
                .eq(SysUser::getUsername, openId)
                .one();
    }

    private String getDepartNameByOpenId(String openId) {
        SysUserDepart sysUserDepart = iSysUserDepartService.lambdaQuery()
                .select(SysUserDepart::getDepId)
                .eq(SysUserDepart::getUserId, openId)
                .one();
        if (sysUserDepart != null) {
            SysDepart sysDepart = departService.lambdaQuery()
                    .select(SysDepart::getDepartName)
                    .eq(SysDepart::getId, sysUserDepart.getDepId())
                    .one();
            if (sysDepart != null) {
                return sysDepart.getDepartName();
            }
        }
        return "无";
    }

    private EScheduleUserCount getUserCountByOpenId(String openId) {
        return iEScheduleUserCountService.lambdaQuery()
                .select(EScheduleUserCount::getReadCount, EScheduleUserCount::getUnreadCount,
                        EScheduleUserCount::getCompletedCount, EScheduleUserCount::getUncompletedCount)
                .eq(EScheduleUserCount::getUserId, openId)
                .one();
    }
}
